import requests

from django.http import JsonResponse
from django_filters.rest_framework import DjangoFilterBackend

from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.filters import SearchFilter,OrderingFilter

from XApiTestServer.pagination import MyPageNumberPagination
from XApiTestServer.serializers import MockSerializer

from XApiTestServer.utils.common import *
from XApiTestServer.utils.test_report import *
from XApiTestServer.utils.convertor import *
from XApiTestServer.utils.response import *
from rest_framework import status
from XApiTestServer.utils.auth import get_username


method_list = [
    "GET", "POST", "PUT", "PATCH", "DELETE", "COPY", "HEAD", "OPTIONS",
    "LINK", "UNLINK", "PURGE", "LOCK", "UNLOCK", "PROPFIND", "VIEW"
]

def testmock(request):
    kwargs = json.loads(request.body.decode('utf-8'))
    mock_id = kwargs['id']
    method = MockInfo.objects.filter(id=mock_id).values('request_method')[0]['request_method']
    url = MockInfo.objects.filter(id=mock_id).values('mock_url')[0]['mock_url']

    if settings.DEBUG:
        mock_url = 'http://127.0.0.1:8000/mock/'+ url
    else:
        mock_url = 'http://127.0.0.1:8082/mock/'+ url
    logger.info("Test Mock Index: {mock_id},The Url is:{mock_url}, Request Method is:{method}".format(mock_id=mock_id,mock_url=mock_url, method=method))
    if method == 'GET':
        response = requests.get(url=mock_url)
    elif method == 'POST':
        response = requests.post(url=mock_url)

    logger.info("Test Mock Response is:{}".format(response.text))
    response_body = SUCCESS_INFO
    response_body['data'] = response.text
    return JsonResponse(response_body)

class MockViewSet(viewsets.ModelViewSet):
    queryset = MockInfo.objects.all()
    serializer_class = MockSerializer
    pagination_class = MyPageNumberPagination
    filter_backends = (OrderingFilter, SearchFilter, DjangoFilterBackend)
    search_fields = ('name',)
    filterset_fields = ('request_method',)
    ordering_fields = ('update_time', )

    def nameValidator(self, mockname, mock_id = None):
        #校验name是否重复
        if mock_id:
            actualname = MockInfo.objects.filter(id=mock_id).values('name')
            if actualname[0]['name'] == mockname:
                return False
            else:
                mocklist = MockInfo.objects.all().values('name')
                for a in mocklist:
                    if a['name'] == mockname:
                        return True
                    else:
                        continue
                return False
        else:
            mocklist = MockInfo.objects.all().values('name')
            for a in mocklist:
                if a['name'] == mockname:
                    return True
                else:
                    continue
            return False

    def requestInfoValidator(self, mock_url, request_method,mock_id = None):
        #校验请求方式和url是否重复
        if mock_id:
            actualurl = MockInfo.objects.filter(id=mock_id).values('mock_url')
            actualmethod = MockInfo.objects.filter(id=mock_id).values('request_method')

            if actualurl[0]['mock_url'] == mock_url and actualmethod[0]['request_method'] == request_method:
                return False
            else:
                mocklist = MockInfo.objects.all().values('mock_url', 'request_method')
                for a in mocklist:
                    if a['mock_url'] == mock_url and a['request_method'] == request_method:
                        return True
                    else:
                        continue
                return False
        else:
            mocklist = MockInfo.objects.all().values('mock_url', 'request_method')
            for a in mocklist:
                if a['mock_url'] == mock_url and a['request_method'] == request_method:
                    return True
                else:
                    continue
            return False

    def create(self, request, *args, **kwargs):
        if request.data['name'] == '' or request.data['mock_url'] == '' or request.data['response_body'] == '':
            return Response(VERIFY_FIELDS_HINT, status=status.HTTP_201_CREATED)

        request.data['request'] = vue_request_to_db(request.data['request'])
        request.data['request'] = str(request.data['request'])

        token = request.META.get("HTTP_X_TOKEN", None)
        username=get_username(token)
        request.data['author'] = username

        if self.nameValidator(request.data['name']):
            return Response(MOCK_NAME_EXISTS, status=status.HTTP_201_CREATED)

        if self.requestInfoValidator(request.data['mock_url'], request.data['request_method']):
            return Response(MOCK_REQUEST_EXISTS, status=status.HTTP_201_CREATED)

        serializer = self.get_serializer(data=request.data)
        logger.info("Create Mock, The Mock Content is:{}" .format(request.data))
        if serializer.is_valid():
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            response_body = SUCCESS_ADD
            response_body['data'] = serializer.data
            return Response(response_body, status=status.HTTP_200_OK, headers=headers)
        else:
            response_body = {'msg': '{msg}'.format(msg=serializer.errors)}
            return Response(response_body, status=status.HTTP_200_OK)


    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)

        response_body = SUCCESS_INFO
        response_body['data'] = serializer.data

        response_body['data']['request'] = db_request_to_vue(response_body['data']['request'])
        request_key_list = list(response_body['data']['request']['request'].keys()).copy()
        if 'headers' not in request_key_list:
            response_body['data']['request']['request']['headers'] = []
        logger.info("View Mock, The Mock Content is:{}".format(response_body['data']))
        return Response(response_body)


    def update(self, request, *args, **kwargs):
        if request.data['name'] == '' or request.data['mock_url'] == '' or request.data['response_body'] == '':
            return Response(VERIFY_FIELDS_HINT, status=status.HTTP_201_CREATED)

        request.data['request'] = vue_request_to_db(request.data['request'])
        request.data['request'] = str(request.data['request'])

        token = request.META.get("HTTP_X_TOKEN", None)
        username=get_username(token)
        request.data['author'] = username

        if self.nameValidator(request.data['name'], request.data['id']):
            return Response(MOCK_NAME_EXISTS, status=status.HTTP_201_CREATED)

        if self.requestInfoValidator(request.data['mock_url'], request.data['request_method'], request.data['id']):
            return Response(MOCK_REQUEST_EXISTS, status=status.HTTP_201_CREATED)

        logger.info("Update Mock, The Mock Content is:{}".format(request.data))
        serializer = self.get_serializer(data=request.data)
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)

        if serializer.is_valid(raise_exception=True):
            self.perform_update(serializer)
            response_body = SUCCESS_UPDATE
            response_body['data'] = serializer.data
            return Response(response_body)
        else:
            return Response(response_format(VERIFY_FIELDS_HINT, serializer.errors), status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        logger.info("Delete Mock index: {}".format(instance.id))
        response_body = SUCCESS_DEL
        return Response(response_body)
